package com.cupk.services;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cupk.dtos.CreatePublicationRequest;
import com.cupk.dtos.PublicationDto;
import com.cupk.dtos.PublicationStatsDto;
import com.cupk.dtos.UpdatePublicationRequest;
import com.cupk.entities.Project;
import com.cupk.entities.Publication;
import com.cupk.entities.User;
import com.cupk.exceptions.ResourceNotFoundException;
import com.cupk.mapper.ProjectMapper;
import com.cupk.mapper.PublicationMapper;
import com.cupk.mapper.UserMapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 成果发表服务类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class PublicationService {
    
    private final PublicationMapper publicationMapper;
    private final UserMapper userMapper;
    private final ProjectMapper projectMapper;
    private final ObjectMapper objectMapper;
    
    /**
     * 获取所有成果
     */
    @Transactional(readOnly = true)
    public List<PublicationDto> getAllPublications() {
        log.info("获取所有成果列表");
        return publicationMapper.findAllWithDetails();
    }
    
    /**
     * 根据ID获取成果详情
     */
    @Transactional(readOnly = true)
    public PublicationDto getPublicationById(Long id) {
        log.info("获取成果详情，ID: {}", id);
        PublicationDto publication = publicationMapper.findByIdWithDetails(id);
        if (publication == null) {
            throw new ResourceNotFoundException("成果不存在，ID: " + id);
        }
        

        
        return publication;
    }
    
    /**
     * 获取用户的成果列表
     */
    @Transactional(readOnly = true)
    public List<PublicationDto> getUserPublications(String username) {
        log.info("获取用户成果列表，用户名: {}", username);
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("username", username));
        if (user == null) {
            throw new ResourceNotFoundException("用户不存在: " + username);
        }
        
        return publicationMapper.findByUserIdWithDetails(user.getId());
    }
    
    /**
     * 根据项目ID获取成果列表
     */
    @Transactional(readOnly = true)
    public List<PublicationDto> getPublicationsByProject(Long projectId) {
        log.info("获取项目成果列表，项目ID: {}", projectId);
        // 验证项目是否存在
        Project project = projectMapper.selectById(projectId);
        if (project == null) {
            throw new ResourceNotFoundException("项目不存在，ID: " + projectId);
        }
        
        return publicationMapper.findByProjectIdWithDetails(projectId);
    }
    
    /**
     * 创建新成果
     */
    @Transactional
    public PublicationDto createPublication(CreatePublicationRequest request, String username) {
        log.info("创建新成果: {}", request.getTitle());
        
        // 获取用户信息
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("username", username));
        if (user == null) {
            throw new ResourceNotFoundException("用户不存在: " + username);
        }
        
        // 验证项目是否存在（如果指定了项目）
        if (request.getProjectId() != null) {
            Project project = projectMapper.selectById(request.getProjectId());
            if (project == null) {
                throw new ResourceNotFoundException("项目不存在，ID: " + request.getProjectId());
            }
        }
        
        Publication publication = new Publication();
        publication.setTitle(request.getTitle());
        publication.setAuthors(request.getAuthors());
        publication.setJournalConferenceName(request.getJournal());
        publication.setAbstractText(request.getAbstractText());
        publication.setPublicationYear(request.getPublishDate() != null ? request.getPublishDate().getYear() : null);
        publication.setDoiLink(request.getDoi());
        publication.setProjectId(request.getProjectId());
        publication.setUploaderId(user.getId());
        publication.setDocumentUrl(request.getDocumentUrl());
        publication.setDocumentName(request.getDocumentName());
        publication.setCreatedAt(LocalDateTime.now());
        publication.setUpdatedAt(LocalDateTime.now());

        
        publicationMapper.insert(publication);
        
        log.info("成果创建成功，ID: {}", publication.getId());
        return publicationMapper.findByIdWithDetails(publication.getId());
    }
    
    /**
     * 更新成果信息
     */
    @Transactional
    public PublicationDto updatePublication(Long id, UpdatePublicationRequest request) {
        log.info("更新成果信息，ID: {}", id);
        
        Publication publication = publicationMapper.selectById(id);
        if (publication == null) {
            throw new ResourceNotFoundException("成果不存在，ID: " + id);
        }
        
        // 更新成果信息
        if (request.getTitle() != null) {
            publication.setTitle(request.getTitle());
        }
        if (request.getAuthors() != null) {
            publication.setAuthors(request.getAuthors());
        }
        if (request.getJournal() != null) {
            publication.setJournalConferenceName(request.getJournal());
        }
        if (request.getAbstractText() != null) {
            publication.setAbstractText(request.getAbstractText());
        }
        if (request.getPublishDate() != null) {
            publication.setPublicationYear(request.getPublishDate().getYear());
        }
        if (request.getDoi() != null) {
            publication.setDoiLink(request.getDoi());
        }
        if (request.getProjectId() != null) {
            // 验证项目是否存在
            Project project = projectMapper.selectById(request.getProjectId());
            if (project == null) {
                throw new ResourceNotFoundException("项目不存在，ID: " + request.getProjectId());
            }
            publication.setProjectId(request.getProjectId());
        }
        if (request.getDocumentUrl() != null) {
            publication.setDocumentUrl(request.getDocumentUrl());
        }
        if (request.getDocumentName() != null) {
            publication.setDocumentName(request.getDocumentName());
        }
        
        publication.setUpdatedAt(LocalDateTime.now());
        publicationMapper.updateById(publication);
        
        log.info("成果更新成功，ID: {}", id);
        return publicationMapper.findByIdWithDetails(id);
    }
    
    /**
     * 删除成果
     */
    @Transactional
    public void deletePublication(Long id) {
        log.info("删除成果，ID: {}", id);
        
        Publication publication = publicationMapper.selectById(id);
        if (publication == null) {
            throw new ResourceNotFoundException("成果不存在，ID: " + id);
        }
        
        publicationMapper.deleteById(id);
        log.info("成果删除成功，ID: {}", id);
    }
    
    /**
     * 搜索成果
     */
    @Transactional(readOnly = true)
    public List<PublicationDto> searchPublications(String keyword) {
        log.info("搜索成果，关键词: {}", keyword);
        return publicationMapper.searchPublicationsWithDetails(keyword);
    }
    
    /**
     * 获取成果统计信息
     */
    @Transactional(readOnly = true)
    public PublicationStatsDto getPublicationStats(String username) {
        log.info("获取成果统计信息，用户: {}", username);
        
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("username", username));
        if (user == null) {
            throw new ResourceNotFoundException("用户不存在: " + username);
        }
        
        PublicationStatsDto stats = new PublicationStatsDto();

        // 总数量
        Long totalCount = publicationMapper.selectCount(
            new QueryWrapper<Publication>().eq("uploader_id", user.getId()));
        stats.setTotalCount(totalCount);

        // 其他统计暂时设置为0，因为数据库表结构简单
        stats.setPublishedCount(totalCount); // 假设所有都是已发表
        stats.setDraftCount(0L);

        // 今年发表数量
        int currentYear = LocalDate.now().getYear();
        Long thisYearCount = publicationMapper.countByUserIdAndYear(user.getId(), currentYear);
        stats.setThisYearCount(thisYearCount);

        // 类型统计暂时设置为0
        stats.setJournalCount(0L);
        stats.setConferenceCount(0L);
        stats.setPatentCount(0L);

        // 引用和影响因子暂时设置为0
        stats.setTotalCitations(0L);
        stats.setAverageImpactFactor(BigDecimal.ZERO);
        
        return stats;
    }
    
    /**
     * 检查成果是否可访问
     */
    @Transactional(readOnly = true)
    public boolean isPublicationAccessible(Long publicationId, String username) {
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("username", username));
        if (user == null) {
            return false;
        }
        
        // 管理员可以访问所有成果
        if ("ADMIN".equals(user.getRole())) {
            return true;
        }
        
        Publication publication = publicationMapper.selectById(publicationId);
        if (publication == null) {
            return false;
        }
        
        // 检查是否为成果作者
        return publication.getUploaderId().equals(user.getId());
    }
    
    /**
     * 检查是否为成果作者
     */
    @Transactional(readOnly = true)
    public boolean isPublicationAuthor(Long publicationId, String username) {
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("username", username));
        if (user == null) {
            return false;
        }
        
        Publication publication = publicationMapper.selectById(publicationId);
        if (publication == null) {
            return false;
        }
        
        return publication.getUploaderId().equals(user.getId());
    }
}
